﻿using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;

namespace Singer.Extensions.Excel;

public static partial class ExcelTools
{
    /// <summary>
    /// 将集合导出为Excel
    /// </summary>
    public static async Task ListToExcelAsync<T>(List<T> list, ExportExcelModel model)
    {
        IWorkbook workbook = model.ExcelSuffix switch
        {
            ExcelSuffix.xlsx => new XSSFWorkbook(),
            ExcelSuffix.xls => new HSSFWorkbook(),
            _ => throw new ArgumentException(nameof(ExcelSuffix))
        };
        ISheet sheet = string.IsNullOrWhiteSpace(model.SheetName) ?
            workbook.CreateSheet("Sheet1") : workbook.CreateSheet(model.SheetName);
        if (list.Count > 0 && model.ExcelColums.Where(x => !x.Ignore).Count() > 0)
        {
            //标题行
            IRow titleRow = sheet.CreateRow(0);
            Type type = typeof(T);

            int columIndex = 0;
            foreach (var property in type.GetProperties())
            {
                ExcelColum? colum = model.ExcelColums.FirstOrDefault(x => x.Name == property.Name);
                if (colum == null || colum.Ignore)
                    continue;
                ICell cell = titleRow.CreateCell(columIndex++);
                var columName = colum.Title;
                cell.SetCellValue(columName);
            }
            //数据
            for (int r = 0; r < list.Count; r++)
            {
                IRow row = sheet.CreateRow(r + 1);
                columIndex = 0;
                foreach (var property in type.GetProperties())
                {
                    ExcelColum? colum = model.ExcelColums.FirstOrDefault(x => x.Name == property.Name);
                    if (colum == null || colum.Ignore)
                        continue;
                    ICell cell = row.CreateCell(columIndex++);
                    cell.SetCellValue(property.GetValue(list[r])?.ToString() ?? "");
                }
            }
        }
        //保存为excel文件
        using MemoryStream stream = new MemoryStream();
        workbook.Write(stream);
        var buf = stream.ToArray();
        using FileStream fileStream = new FileStream(model.FilePath, FileMode.Create, FileAccess.Write);
        await fileStream.WriteAsync(buf, 0, buf.Length);
        await fileStream.FlushAsync();
    }
}
